package com.isyscore.os.etl.model.flinkviewable;

import com.isyscore.os.etl.constant.JobConstant;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author : zhan9yn
 * @version : 1.0
 * @date : 2021/12/14 2:49 下午
 */
public class TypeConvert {
    private static final Map<String, String> MYSQL_TYPE_MAP = Collections.unmodifiableMap(new HashMap(){{
        //mysql type convert
        put("TINYINT", "TINYINT");
        put("SMALLINT", "SMALLINT");
        put("TINYINT", "SMALLINT");
        put("UNSIGNED", "SMALLINT");
        put("INT", "INT");
        put("MEDIUMINT", "INT");
        put("SMALLINT", "INT");
        put("UNSIGNED", "INT");
        put("INT UNSIGNED", "BIGINT");
        put("BIGINT UNSIGNED", "DECIMAL(20, 0)");
        put("BIGINT", "BIGINT");
        put("FLOAT", "FLOAT");
        put("DOUBLE", "DOUBLE");
        put("DOUBLE PRECISION", "DOUBLE");
        put("DOUBLE PRECISION", "DOUBLE");
        put("NUMERIC", "DECIMAL(38, 18)");
        put("DECIMAL", "DECIMAL(38, 18)");
        put("BOOLEAN", "BOOLEAN");
        put("TINYINT(1)", "BOOLEAN");
        put("DATE", "DATE");
        put("TIME", "TIME");
        put("DATETIME", "TIMESTAMP");
        put("CHAR", "STRING");
        put("VARCHAR", "STRING");
        put("TEXT", "STRING");
        put("BINARY", "BYTES");
        put("VARBINARY", "BYTES");
        put("BLOB", "BYTES");
    }});

    private static final Map<String, String> PG_TYPE_MAP = Collections.unmodifiableMap(new HashMap(){{
        //pgsql type convert
        put("SMALLINT", "SMALLINT");
        put("INT2", "SMALLINT");
        put("SMALLSERIAL", "SMALLINT");
        put("SERIAL2", "SMALLINT");
        put("INTEGER", "INT");
        put("SERIAL", "INT");
        put("INT4", "INT");
        put("BIGINT", "BIGINT");
        put("BIGSERIAL", "BIGINT");
        put("OID", "BIGINT");
        put("INT8", "BIGINT");
        put("REAL", "FLOAT");
        put("FLOAT4", "FLOAT");
        put("FLOAT8", "DOUBLE");
        put("DOUBLE PRECISION", "DOUBLE");
        put("NUMERIC", "DECIMAL(38, 18)");
        put("DECIMAL", "DECIMAL(38, 18)");
        put("BOOLEAN", "BOOLEAN");
        put("DATE", "DATE");
        put("TIME", "TIME");
        put("TIMETZ", "TIME");
        put("TIMESTAMP", "TIMESTAMP");
        put("TIMESTAMPTZ", "TIMESTAMP");
        put("CHAR", "STRING");
        put("CHARACTER", "STRING");
        put("VARCHAR", "STRING");
        put("CHARACTER VARYING", "STRING");
        put("TEXT", "STRING");
        put("NAME", "STRING");
        put("BPCHAR", "STRING");
        put("BYTEA", "BYTES");
        put("ARRAY", "ARRAY");
    }});
    private static final Map<String, String> CLICKHOUSE_TYPE_MAP = Collections.unmodifiableMap(new HashMap(){{
        put("BOOLEAN", "BOOLEAN");
        put("TINYINT", "TINYINT");
        put("INT8", "TINYINT");
        put("UINT8", "TINYINT");
        put("SMALLINT", "SMALLINT");
        put("UINT16", "SMALLINT");
        put("INT16", "SMALLINT");
        put("INTEGER", "INT");
        put("INTERVALYEAR", "INT");
        put("INTERVALQUARTER", "INT");
        put("INTERVALMONTH", "INT");
        put("INTERVALWEEK", "INT");
        put("INTERVALDAY", "INT");
        put("INTERVALHOUR", "INT");
        put("INTERVALMINUTE", "INT");
        put("INTERVALSECOND", "INT");
        put("INTERVALSECOND", "INT");
        put("INT32", "INT");
        put("INT", "INT");
        put("UINT32", "BIGINT");
        put("UINT64", "BIGINT");
        put("INT64", "BIGINT");
        put("BIGINT", "BIGINT");
        put("FLOAT", "FLOAT");
        put("FLOAT32", "FLOAT");
        put("DECIMAL", "DECIMAL(38,18)");
        put("DECIMAL32", "DECIMAL(38,18)");
        put("DECIMAL64", "DECIMAL(38,18)");
        put("DECIMAL128", "DECIMAL(38,18)");
        put("DEC", "DECIMAL(38,18)");
        put("DOUBLE", "DOUBLE");
        put("FLOAT64", "DOUBLE");
        put("UUID", "STRING");
        put("COLLECTION", "STRING");
        put("BLOB", "STRING");
        put("LONGTEXT", "STRING");
        put("TINYTEXT", "STRING");
        put("TEXT", "STRING");
        put("CHAR", "STRING");
        put("MEDIUMTEXT", "STRING");
        put("TINYBLOB", "STRING");
        put("MEDIUMBLOB", "STRING");
        put("LONGBLOB", "STRING");
        put("BINARY", "STRING");
        put("STRUCT", "STRING");
        put("VARCHAR", "STRING");
        put("STRING", "STRING");
        put("ENUM8", "STRING");
        put("ENUM16", "STRING");
        put("FIXEDSTRING", "STRING");
        put("NESTED", "STRING");
        put("DATE", "DATE");
        put("TIME", "TIME");
        put("TIMESTAMP", "TIMESTAMP");
        put("DATETIME", "TIMESTAMP");
        put("NOTHING", "NULL");
        put("NULLABLE", "NULL");
        put("NULL", "NULL");
    }});
    private static final Map<String, String> ORACLE_TYPE_MAP = Collections.unmodifiableMap(new HashMap(){{
        //oracle
        put("SMALLINT","SMALLINT");
        put("BINARY_DOUBLE","DOUBLE");
        put("CHAR", "STRING");
        put("VARCHAR", "STRING");
        put("VARCHAR2", "STRING");
        put("NVARCHAR2", "STRING");
        put("NCHAR", "STRING");
        put("CLOB", "Clob");
        put("NCLOB", "Clob");
        put("INT", "DECIMAL(38,18)");
        put("INTEGER", "DECIMAL(38,18)");
        put("NUMBER", "DECIMAL(38,18)");
        put("DECIMAL", "DECIMAL(38,18)");
        put("FLOAT", "DECIMAL(38,18)");
        put("DATE", "DATE");
        put("RAW", "BYTES");
        put("LONG RAW", "BYTES");
        put("BLOB", "Blob");
        put("BINARY_FLOAT", "FLOAT");
    }});

    private static final Map<String, String> DM_TYPE_MAP = Collections.unmodifiableMap(new HashMap(){{
        put("CHAR", "STRING");
        put("VARCHAR", "STRING");
        put("VARCHAR2", "STRING");
        put("CHARACTER", "STRING");
        put("CLOB", "STRING");
        put("TEXT", "STRING");
        put("LONG", "STRING");
        put("LONGVARCHAR", "STRING");
        put("ENUM", "STRING");
        put("SET", "STRING");
        put("JSON", "STRING");
        put("DECIMAL", "DECIMAL(38,18)");
        put("DEC", "DECIMAL(38,18)");
        put("NUMERIC", "DECIMAL(38,18)");
        put("NUMBER", "DECIMAL(38,18)");
        put("INT", "INT");
        put("INTEGER", "INT");
        put("TINYINT", "TINYINT");
        put("BYTE", "TINYINT");
        put("BYTES", "TINYINT");
        put("SMALLINT", "SMALLINT");
        put("BIGINT", "BIGINT");
        put("BINARY", "BYTES");
        put("VARBINARY", "BYTES");
        put("BLOB", "BYTES");
        put("TINYBLOB", "BYTES");
        put("MEDIUMBLOB", "BYTES");
        put("LONGBLOB", "BYTES");
        put("GEOMETRY", "BYTES");
        put("IMAGE", "BYTES");
        put("REAL", "FLOAT");
        put("FLOAT", "DOUBLE");
        put("DOUBLE PRECISION", "DOUBLE");
        put("BIT", "BOOLEAN");
        put("DATE", "DATE");
        put("YEAR", "DATE");
        put("TIME", "DATE");
        put("TIMESTAMP", "TIMESTAMP(6)");
        put("DATETIME", "TIMESTAMP(6)");
    }});
    private static final Map<String, String> MS_TYPE_MAP = Collections.unmodifiableMap(new HashMap(){{
        put("BIT", "BOOLEAN");
        put("BIGINT", "BIGINT");
        put("TINYINT", "TINYINT");
        put("INT", "INT");
        put("SMALLINT", "INT");
        put("INT IDENTITY", "INT");
        put("REAL", "FLOAT");
        put("FLOAT", "DOUBLE");
        put("DECIMAL", "DECIMAL DECIMAL(1,0)");
        put("NUMERIC", "DECIMAL DECIMAL(1,0)");
        put("CHAR", "STRING");
        put("VARCHAR", "STRING");
        put("VARCHAR(MAX)", "STRING");
        put("TEXT", "STRING");
        put("XML", "STRING");
        put("NCHAR", "STRING");
        put("NVARCHAR", "STRING");
        put("NVARCHAR(MAX)", "STRING");
        put("NTEXT", "STRING");
        put("TIME", "STRING");
        put("DATETIME2", "STRING");
        put("DATETIMEOFFSET", "STRING");
        put("UNIQUEIDENTIFIER", "STRING");
        put("DATE", "DATE");
        put("DATETIME", "TIMESTAMP");
        put("SMALLDATETIME", "TIMESTAMP");
        put("BINARY", "BYTES");
        put("VARBINARY", "BYTES");
        put("IMAGE", "BYTES");
        put("MONEY", "DECIMAL(1,0)");
        put("SMALLMONEY", "DECIMAL(1,0)");
    }});

    public static String getType (int type, String rowType) {
        rowType = rowType.toUpperCase().trim();
        String res = null;
        if (Objects.equals(JobConstant.MYSQL_TYPE, type)){
            res = MYSQL_TYPE_MAP.get(rowType);
        } else if (Objects.equals(JobConstant.ORACLE_TYPE, type)){
            res = ORACLE_TYPE_MAP.get(rowType);
        } else if (Objects.equals(JobConstant.CLICKHOUSE_TYPE, type)){
            res =CLICKHOUSE_TYPE_MAP.get(rowType);
        }else if (Objects.equals(JobConstant.SQLSERVER_TYPE, type)) {
            res =MS_TYPE_MAP.get(rowType);
        } else if (Objects.equals(JobConstant.TD_TYPE, type)){

        }else if (Objects.equals(JobConstant.PG_TYPE, type)){
            res = PG_TYPE_MAP.get(rowType);
        } else if (Objects.equals(JobConstant.DM_TYPE, type))
            res = DM_TYPE_MAP.get(rowType);
        if (res != null) {
            return res;
        } else {
            return "STRING";
        }
    }
}
